home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2004 March / PCWMAR04.iso / Software / Trial / TestTrack Pro 6 / ttprowininstall.exe / %LSMAINDIR% / LicenseServer Help / wwhelp / wwhimpl / js / scripts / index.js < prev    next >
Encoding:
JavaScript  |  2003-12-12  |  43.4 KB  |  1,538 lines

  1. // Copyright (c) 2000-2001 Quadralay Corporation.  All rights reserved.
  2. //
  3.  
  4. function  WWHIndex_Object()
  5. {
  6.   this.mbPanelInitialized = false;
  7.   this.mPanelAnchor       = null;
  8.   this.mPanelTabTitle     = WWHFrame.WWHJavaScript.mMessages.mTabsIndexLabel;
  9.   this.mInitIndex         = 0;
  10.   this.mOptions           = new WWHIndexOptions_Object();
  11.   this.mTopEntry          = new WWHIndexTopEntry_Object();
  12.   this.mMaxLevel          = 0;
  13.   this.mEntryCount        = 0;
  14.   this.mSeeAlsoArray      = new Array();
  15.   this.mSectionIndex      = null;
  16.   this.mSectionCache      = new WWHSectionCache_Object();
  17.   this.mIterator          = new WWHIndexIterator_Object();
  18.   this.mHTMLSegment       = new WWHStringBuffer_Object();
  19.   this.mEventString       = WWHPopup_EventString();
  20.   this.mClickedEntry      = null;
  21.  
  22.   this.fInitHeadHTML          = WWHIndex_InitHeadHTML;
  23.   this.fInitBodyHTML          = WWHIndex_InitBodyHTML;
  24.   this.fInitLoadBookIndex     = WWHIndex_InitLoadBookIndex;
  25.   this.fAddSeeAlsoEntry       = WWHIndex_AddSeeAlsoEntry;
  26.   this.fProcessSeeAlsoEntries = WWHIndex_ProcessSeeAlsoEntries;
  27.   this.fHeadHTML              = WWHIndex_HeadHTML;
  28.   this.fStartHTMLSegments     = WWHIndex_StartHTMLSegments;
  29.   this.fAdvanceHTMLSegment    = WWHIndex_AdvanceHTMLSegment;
  30.   this.fGetHTMLSegment        = WWHIndex_GetHTMLSegment;
  31.   this.fEndHTMLSegments       = WWHIndex_EndHTMLSegments;
  32.   this.fHoverTextTranslate    = WWHIndex_HoverTextTranslate;
  33.   this.fHoverTextFormat       = WWHIndex_HoverTextFormat;
  34.   this.fGetPopupAction        = WWHIndex_GetPopupAction;
  35.   this.fThresholdExceeded     = WWHIndex_ThresholdExceeded;
  36.   this.fGetSectionNavigation  = WWHIndex_GetSectionNavigation;
  37.   this.fChangeSection         = WWHIndex_ChangeSection;
  38.   this.fSelectionListHeadHTML = WWHIndex_SelectionListHeadHTML;
  39.   this.fSelectionListBodyHTML = WWHIndex_SelectionListBodyHTML;
  40.   this.fDisplayLink           = WWHIndex_DisplayLink;
  41.   this.fGetEntry              = WWHIndex_GetEntry;
  42.   this.fClickedEntry          = WWHIndex_ClickedEntry;
  43.   this.fClickedSeeAlsoEntry   = WWHIndex_ClickedSeeAlsoEntry;
  44.  
  45.   // Set options
  46.   //
  47.   WWHJavaScriptSettings_Index_DisplayOptions(this.mOptions);
  48. }
  49.  
  50. function  WWHIndex_InitHeadHTML()
  51. {
  52.   var  InitHeadHTML = "";
  53.  
  54.  
  55.   return InitHeadHTML;
  56. }
  57.  
  58. function  WWHIndex_InitBodyHTML()
  59. {
  60.   var  HTML = new WWHStringBuffer_Object();
  61.   var  BookList = WWHFrame.WWHHelp.mBooks.mBookList;
  62.   var  bFoundRequiredGroupOptions = false;
  63.   var  RequiredGroup = null;
  64.   var  MaxIndex;
  65.   var  Index;
  66.   var  bRequiredGroupShowBuckets;
  67.   var  ItemKey;
  68.   var  Item;
  69.  
  70.  
  71.   // Display initializing message
  72.   //
  73.   HTML.fAppend("<h2>" + WWHFrame.WWHJavaScript.mMessages.mInitializingMessage + "</h2>\n");
  74.  
  75.   // Load index data
  76.   //
  77.   this.mInitIndex = 0;
  78.   for (MaxIndex = BookList.length, Index = 0 ; Index < MaxIndex ; Index++)
  79.   {
  80.     // Reference Index data
  81.     //
  82.     HTML.fAppend("<script language=\"JavaScript1.2\" src=\"" + WWHFrame.WWHHelp.mHelpURLPrefix + WWHStringUtilities_RestoreEscapedSpaces(BookList[Index].mDirectory) + "wwhdata/js/index.js\"></script>\n");
  83.  
  84.     // Load Index data for current book
  85.     //
  86.     HTML.fAppend("<script language=\"JavaScript1.2\" src=\"" + WWHFrame.WWHHelp.mHelpURLPrefix + "wwhelp/wwhimpl/js/scripts/index1s.js\"></script>\n");
  87.   }
  88.  
  89.   // Confirm required group options are defined
  90.   //
  91.   for (MaxIndex = this.mOptions.mGroupList.length, Index = 0 ; Index < MaxIndex ; Index++)
  92.   {
  93.     if (this.mOptions.mGroupList[Index].length == 0)  // Required Group
  94.     {
  95.       bFoundRequiredGroupOptions = true;
  96.     }
  97.   }
  98.  
  99.   // Create required group options if not found
  100.   //
  101.   if ( ! bFoundRequiredGroupOptions)
  102.   {
  103.     this.mOptions.fGroup("", true, false, "");
  104.   }
  105.  
  106.   // Create always display entries
  107.   //
  108.   for (MaxIndex = this.mOptions.mGroupList.length, Index = 0 ; Index < MaxIndex ; Index++)
  109.   {
  110.     if (this.mOptions.mGroupList[Index].length == 0)  // Required group
  111.     {
  112.       RequiredGroup = this.mTopEntry.fGetGroup(this.mOptions.mGroupList[Index]);
  113.     }
  114.     else if (this.mOptions.mGroupInfoHash[this.mOptions.mGroupList[Index] + "~"].mbAlwaysDisplay)  // Always display grouping
  115.     {
  116.       this.mTopEntry.fGetGroup(this.mOptions.mGroupList[Index]);
  117.     }
  118.   }
  119.  
  120.   // Determine if buckets are going to be hidden
  121.   //
  122.   bRequiredGroupShowBuckets = this.mOptions.mGroupInfoHash["" + "~"].mbShowBuckets;
  123.  
  124.   // Add require items to required group
  125.   //
  126.   for (ItemKey in this.mOptions.mGroupMapping)
  127.   {
  128.     if (this.mOptions.mGroupMapping[ItemKey].length == 0)  // Required item
  129.     {
  130.       Item = ItemKey.substring(0, ItemKey.length - 1);
  131.       RequiredGroup.fGetBucket(Item, bRequiredGroupShowBuckets);
  132.     }
  133.   }
  134.  
  135.   return HTML.fGetBuffer();
  136. }
  137.  
  138. function  WWHIndex_InitLoadBookIndex(ParamAddIndexEntriesFunc)
  139. {
  140.   // Load Index
  141.   //
  142.   ParamAddIndexEntriesFunc(this.mTopEntry);
  143.  
  144.   // Increment init book index
  145.   //
  146.   this.mInitIndex++;
  147.  
  148.   // Check if done
  149.   //
  150.   if (this.mInitIndex == WWHFrame.WWHHelp.mBooks.mBookList.length)
  151.   {
  152.     // Process see also entries to set up links between source and target
  153.     // Do this before the top level hashes are cleared by the sort children call
  154.     //
  155.     this.fProcessSeeAlsoEntries();
  156.  
  157.     // Sort top level entries
  158.     //
  159.     if (this.mTopEntry.mChildrenSortArray == null)
  160.     {
  161.       WWHIndexEntry_SortChildren(this.mTopEntry);
  162.     }
  163.  
  164.     // Panel is initialized
  165.     //
  166.     this.mbPanelInitialized = true;
  167.   }
  168. }
  169.  
  170. function  WWHIndex_AddSeeAlsoEntry(ParamEntry)
  171. {
  172.   this.mSeeAlsoArray[this.mSeeAlsoArray.length] = ParamEntry;
  173. }
  174.  
  175. function  WWHIndex_ProcessSeeAlsoEntries()
  176. {
  177.   var  MaxIndex;
  178.   var  Index;
  179.   var  FirstChar;
  180.   var  GroupTitle;
  181.   var  SeeAlsoTargetEntry;
  182.   var  GroupEntry;
  183.   var  BucketEntry;
  184.  
  185.  
  186.   for (MaxIndex = this.mSeeAlsoArray.length, Index = 0 ; Index < MaxIndex ; Index++)
  187.   {
  188.     SeeAlsoEntry = this.mSeeAlsoArray[Index];
  189.  
  190.     // Determine location of see also target
  191.     //
  192.     if (SeeAlsoEntry.mSeeAlso.length > 0)
  193.     {
  194.       FirstChar = SeeAlsoEntry.mSeeAlso.substring(0, 1);
  195.  
  196.       // toUpperCase is conditional to handle numbers
  197.       //
  198.       FirstChar = (typeof FirstChar.toUpperCase == "function") ? FirstChar.toUpperCase() : FirstChar;
  199.  
  200.       GroupTitle = WWHFrame.WWHIndex.mOptions.mGroupMapping[FirstChar + "~"];
  201.       if (typeof GroupTitle == "undefined")
  202.       {
  203.         GroupTitle = "";  // Put in required grouping
  204.       }
  205.  
  206.       // Access target entry
  207.       //
  208.       SeeAlsoTargetEntry = null;
  209.       GroupEntry = this.mTopEntry.mChildren[GroupTitle + "~"];
  210.       if ((typeof GroupEntry != "undefined") &&
  211.           (GroupEntry.mChildren != null))
  212.       {
  213.         BucketEntry = GroupEntry.mChildren[FirstChar + "~"];
  214.         if ((typeof BucketEntry != "undefined") &&
  215.             (BucketEntry.mChildren != null))
  216.         {
  217.           SeeAlsoTargetEntry = BucketEntry.mChildren[SeeAlsoEntry.mSeeAlso + "~"];
  218.           if (typeof SeeAlsoTargetEntry == "undefined")
  219.           {
  220.             SeeAlsoTargetEntry = null;
  221.           }
  222.         }
  223.       }
  224.  
  225.       // Setup links between source and destination
  226.       //
  227.       if (SeeAlsoTargetEntry != null)
  228.       {
  229.         // See if target entry is already tagged
  230.         //
  231.         if (typeof SeeAlsoTargetEntry.mSeeAlsoTargetName == "undefined")
  232.         {
  233.           // Update target entry
  234.           //
  235.           SeeAlsoTargetEntry.mSeeAlsoTargetName = "s" + Index;
  236.         }
  237.  
  238.         // Update source entry
  239.         //
  240.         SeeAlsoEntry.mSeeAlsoTargetName = SeeAlsoTargetEntry.mSeeAlsoTargetName;
  241.         SeeAlsoEntry.mSeeAlsoTargetEntryKey = (GroupTitle.length > 0) ? GroupTitle : FirstChar;
  242.       }
  243.     }
  244.   }
  245. }
  246.  
  247. function  WWHIndex_HeadHTML()
  248. {
  249.   var  HTML = new WWHStringBuffer_Object();
  250.   var  MaxLevel;
  251.   var  Level;
  252.  
  253.  
  254.   // Generate style section
  255.   //
  256.   HTML.fAppend("<style type=\"text/css\">\n");
  257.   HTML.fAppend(" <!--\n");
  258.   HTML.fAppend("  a.navigation { text-decoration: none ;\n");
  259.   HTML.fAppend("                 color: " + WWHFrame.WWHJavaScript.mSettings.mIndex.mNavigationEnabledColor + " }\n");
  260.   HTML.fAppend("  p.navigation { margin-top: 1pt ;\n");
  261.   HTML.fAppend("                 margin-bottom: 1pt ;\n");
  262.   HTML.fAppend("                 color: " + WWHFrame.WWHJavaScript.mSettings.mIndex.mNavigationCurrentColor + " ;\n");
  263.   HTML.fAppend("                 " + WWHFrame.WWHJavaScript.mSettings.mIndex.mNavigationFontStyle + " }\n");
  264.   HTML.fAppend("  a            { text-decoration: none ;\n");
  265.   HTML.fAppend("                 color: " + WWHFrame.WWHJavaScript.mSettings.mIndex.mEnabledColor + " }\n");
  266.   HTML.fAppend("  a.AnchorOnly { text-decoration: none ;\n");
  267.   HTML.fAppend("                 color: " + WWHFrame.WWHJavaScript.mSettings.mIndex.mDisabledColor + " }\n");
  268.   HTML.fAppend("  p            { margin-top: 1pt ;\n");
  269.   HTML.fAppend("                 margin-bottom: 1pt ;\n");
  270.   HTML.fAppend("                 color: " + WWHFrame.WWHJavaScript.mSettings.mIndex.mDisabledColor + " ;\n");
  271.   HTML.fAppend("                 " + WWHFrame.WWHJavaScript.mSettings.mIndex.mFontStyle + " }\n");
  272.   for (MaxLevel = this.mMaxLevel + 1, Level = 0 ; Level <= MaxLevel ; Level++)
  273.   {
  274.     HTML.fAppend("  p.l" + Level + " { margin-left: " + (WWHFrame.WWHJavaScript.mSettings.mIndex.mIndent * Level) + "pt }\n");
  275.   }
  276.   HTML.fAppend(" -->\n");
  277.   HTML.fAppend("</style>\n");
  278.  
  279.   return HTML.fGetBuffer();
  280. }
  281.  
  282. function  WWHIndex_StartHTMLSegments()
  283. {
  284.   var  HTML = new WWHStringBuffer_Object();
  285.  
  286.  
  287.   if (this.fThresholdExceeded())
  288.   {
  289.     // Display sections of the index rather than the whole thing
  290.     //
  291.  
  292.     // Select first entry if section not already picked
  293.     //
  294.     if (this.mSectionIndex == null)
  295.     {
  296.       this.mSectionIndex = 0;
  297.     }
  298.  
  299.     // Calculate section navigation if not already cached
  300.     //
  301.     if (typeof this.mSectionCache[this.mSectionIndex] == "undefined")
  302.     {
  303.       this.mSectionCache[this.mSectionIndex] = this.fGetSectionNavigation(this.mSectionIndex);
  304.     }
  305.  
  306.     // Display section selection
  307.     //
  308.     HTML.fAppend(this.mSectionCache[this.mSectionIndex]);
  309.     HTML.fAppend("<p> </p>\n");
  310.   }
  311.   else
  312.   {
  313.     // Display whole index
  314.     //
  315.     this.mSectionIndex = null;
  316.   }
  317.  
  318.   // Setup iterator for display
  319.   //
  320.   this.mIterator.fReset(this.mSectionIndex, this.fThresholdExceeded());
  321.  
  322.   // Define accessor functions to reduce file size
  323.   //
  324.   HTML.fAppend("<script type=\"text/javascript\" language=\"JavaScript1.2\">\n");
  325.   HTML.fAppend(" <!--\n");
  326.   HTML.fAppend("  function  fC(ParamEntryInfo)\n");
  327.   HTML.fAppend("  {\n");
  328.   HTML.fAppend("    WWHFrame.WWHIndex.fClickedEntry(ParamEntryInfo);\n");
  329.   HTML.fAppend("  }\n");
  330.   HTML.fAppend("\n");
  331.   HTML.fAppend("  function  fA(ParamEntryInfo)\n");
  332.   HTML.fAppend("  {\n");
  333.   HTML.fAppend("    WWHFrame.WWHIndex.fClickedSeeAlsoEntry(ParamEntryInfo);\n");
  334.   HTML.fAppend("  }\n");
  335.   HTML.fAppend("\n");
  336.   HTML.fAppend("  function  fS(ParamEntryID,\n");
  337.   HTML.fAppend("               ParamEvent)\n");
  338.   HTML.fAppend("  {\n");
  339.   HTML.fAppend("    WWHFrame.WWHJavaScript.mPanels.mPopup.fShow(ParamEntryID, ParamEvent);\n");
  340.   HTML.fAppend("  }\n");
  341.   HTML.fAppend("\n");
  342.   HTML.fAppend("  function  fH()\n");
  343.   HTML.fAppend("  {\n");
  344.   HTML.fAppend("    WWHFrame.WWHJavaScript.mPanels.mPopup.fHide();\n");
  345.   HTML.fAppend("  }\n");
  346.   HTML.fAppend("  function  fN(ParamSectionIndex)\n");
  347.   HTML.fAppend("  {\n");
  348.   HTML.fAppend("    WWHFrame.WWHIndex.fChangeSection(ParamSectionIndex);\n");
  349.   HTML.fAppend("  }\n");
  350.   HTML.fAppend(" // -->\n");
  351.   HTML.fAppend("</script>\n");
  352.  
  353.   return HTML.fGetBuffer();
  354. }
  355.  
  356. function  WWHIndex_AdvanceHTMLSegment()
  357. {
  358.   var  MaxHTMLSegmentSize = WWHFrame.WWHJavaScript.mMaxHTMLSegmentSize;
  359.   var  Entry;
  360.   var  MaxIndex;
  361.   var  Index;
  362.   var  BaseEntryInfo = "";
  363.   var  EntryInfo;
  364.   var  EntryAnchorName;
  365.   var  EntryPrefix;
  366.   var  EntrySuffix;
  367.  
  368.  
  369.   // Add index in top entry to entry info if IteratorScope != TopEntry
  370.   //
  371.   if (this.mSectionIndex != null)
  372.   {
  373.     BaseEntryInfo += this.mSectionIndex;
  374.   }
  375.  
  376.   this.mHTMLSegment.fReset();
  377.   while ((this.mHTMLSegment.fSize() < MaxHTMLSegmentSize) &&
  378.          (this.mIterator.fAdvance()))
  379.   {
  380.     Entry = this.mIterator.mEntry;
  381.  
  382.     // Check to see if this entry should be displayed
  383.     //
  384.     if ((Entry.mbBucket) &&
  385.         ( ! Entry.mbShow))
  386.     {
  387.       // Don't display hidden buckets
  388.       //
  389.  
  390.       // Do display break between other entries and first required entry
  391.       //
  392.       if (Entry.mbFirstRequiredEntry)
  393.       {
  394.         this.mHTMLSegment.fAppend("<p> </p>\n");
  395.       } 
  396.     }
  397.     else
  398.     {
  399.       // Insert breaks between sections
  400.       //
  401.       if ((Entry.mbGroup) ||
  402.           (Entry.mbBucket))
  403.       {
  404.         this.mHTMLSegment.fAppend("<p> </p>\n");
  405.       }
  406.  
  407.       // See if entry needs a named anchor target
  408.       //
  409.       if (typeof Entry.mSeeAlsoTargetName == "string")
  410.       {
  411.         EntryAnchorName = " name=\"" + Entry.mSeeAlsoTargetName + "\"";
  412.       }
  413.       else
  414.       {
  415.         EntryAnchorName = "";
  416.       }
  417.  
  418.       // Determine entry type
  419.       //
  420.       if (Entry.mbGroup)
  421.       {
  422.         EntryPrefix = "<b>";
  423.         EntrySuffix = "</b>";
  424.       }
  425.       else if (Entry.mbBucket)
  426.       {
  427.         EntryPrefix = "<b>";
  428.         EntrySuffix = "</b>";
  429.       }
  430.       else if (typeof Entry.mSeeAlso == "string")
  431.       {
  432.         if (typeof Entry.mSeeAlsoTargetName == "string")
  433.         {
  434.           // Use position stack for link info
  435.           //
  436.           EntryInfo = BaseEntryInfo;
  437.           for (MaxIndex = this.mIterator.mPositionStack.length, Index = 0 ; Index < MaxIndex ; Index++)
  438.           {
  439.             if (EntryInfo.length > 0)
  440.             {
  441.               EntryInfo += ":";
  442.             }
  443.             EntryInfo += this.mIterator.mPositionStack[Index];
  444.           }
  445.  
  446.           EntryPrefix = "<i><a href=\"javascript:fA('" + EntryInfo + "');\"" + this.fGetPopupAction(EntryInfo) + ">";
  447.           EntrySuffix = "</a></i>";
  448.         }
  449.         else
  450.         {
  451.           EntryPrefix = "<i>";
  452.           EntrySuffix = "</i>";
  453.         }
  454.       }
  455.       else if (Entry.mBookLinks != null)
  456.       {
  457.         // Use position stack for link info
  458.         //
  459.         EntryInfo = BaseEntryInfo;
  460.         for (MaxIndex = this.mIterator.mPositionStack.length, Index = 0 ; Index < MaxIndex ; Index++)
  461.         {
  462.           if (EntryInfo.length > 0)
  463.           {
  464.             EntryInfo += ":";
  465.           }
  466.           EntryInfo += this.mIterator.mPositionStack[Index];
  467.         }
  468.  
  469.         EntryPrefix = "<a" + EntryAnchorName + " href=\"javascript:fC('" + EntryInfo + "');\"" + this.fGetPopupAction(EntryInfo) + ">";
  470.         EntrySuffix = "</a>";
  471.       }
  472.       else if (EntryAnchorName.length > 0)
  473.       {
  474.         EntryPrefix = "<a class=\"AnchorOnly\"" + EntryAnchorName + ">";
  475.         EntrySuffix = "</a>";
  476.       }
  477.       else
  478.       {
  479.         EntryPrefix = "";
  480.         EntrySuffix = "";
  481.       }
  482.  
  483.       this.mHTMLSegment.fAppend("<p class=l" + (this.mIterator.mPositionStack.length - this.mIterator.mStackOffset) + "><nobr>" + EntryPrefix + Entry.mText + EntrySuffix + "</nobr></p>\n");
  484.     }
  485.   }
  486.  
  487.   return (this.mHTMLSegment.fSize() > 0);
  488. }
  489.  
  490. function  WWHIndex_GetHTMLSegment()
  491. {
  492.   return this.mHTMLSegment.fGetBuffer();
  493. }
  494.  
  495. function  WWHIndex_EndHTMLSegments()
  496. {
  497.   var  HTML = "";
  498.  
  499.  
  500.   if ((this.mOptions.mThreshold <= 0) ||
  501.       (this.mEntryCount < this.mOptions.mThreshold))
  502.   {
  503.     ;  // Nothing to do
  504.   }
  505.   else  // Display sections of the Index rather than the whole thing
  506.   {
  507.     // Display section selection
  508.     //
  509. // HACK BEN
  510. //    HTML += "<p> </p>\n";
  511. //    HTML += this.mSectionCache[this.mSectionIndex];
  512.   }
  513.  
  514.   return HTML;
  515. }
  516.  
  517. function  WWHIndex_HoverTextTranslate(ParamEntryInfo)
  518. {
  519.   var  Entry;
  520.  
  521.  
  522.   // Locate specified entry
  523.   //
  524.   Entry = this.fGetEntry(ParamEntryInfo);
  525.  
  526.   return Entry.mText;
  527. }
  528.  
  529. function  WWHIndex_HoverTextFormat(ParamWidth,
  530.                                    ParamTextID,
  531.                                    ParamText)
  532. {
  533.   var  FormattedText   = "";
  534.   var  ForegroundColor = WWHFrame.WWHJavaScript.mSettings.mHoverText.mForegroundColor;
  535.   var  BackgroundColor = WWHFrame.WWHJavaScript.mSettings.mHoverText.mBackgroundColor;  
  536.   var  BorderColor     = WWHFrame.WWHJavaScript.mSettings.mHoverText.mBorderColor;
  537.   var  ImageDir        = WWHFrame.WWHHelp.mHelpURLPrefix + "wwhelp/wwhimpl/common/images";
  538.   var  ReqSpacer1w2h   = "<img src=\"" + ImageDir + "/spc1w2h.gif\" width=1 height=2>";
  539.   var  ReqSpacer2w1h   = "<img src=\"" + ImageDir + "/spc2w1h.gif\" width=2 height=1>";
  540.   var  ReqSpacer1w7h   = "<img src=\"" + ImageDir + "/spc1w7h.gif\" width=1 height=7>";
  541.   var  ReqSpacer5w1h   = "<img src=\"" + ImageDir + "/spc5w1h.gif\" width=5 height=1>";
  542.   var  Spacer1w2h      = ReqSpacer1w2h;
  543.   var  Spacer2w1h      = ReqSpacer2w1h;
  544.   var  Spacer1w7h      = ReqSpacer1w7h;
  545.   var  Spacer5w1h      = ReqSpacer5w1h;
  546.  
  547.  
  548.   // Netscape 6.x (Mozilla) renders table cells with graphics
  549.   // incorrectly inside of <div> tags that are rewritten on the fly
  550.   //
  551.   if (WWHFrame.WWHBrowserInfo.mBrowser == 4)  // Shorthand for Netscape 6.x (Mozilla)
  552.   {
  553.     Spacer1w2h = "";
  554.     Spacer2w1h = "";
  555.     Spacer1w7h = "";
  556.     Spacer5w1h = "";
  557.   }
  558.  
  559.   FormattedText += "<table width=\"" + ParamWidth + "\" border=0 cellspacing=0 cellpadding=0 bgcolor=\"" + BackgroundColor + "\">";
  560.   FormattedText += " <tr>";
  561.   FormattedText += "  <td height=2 colspan=5 bgcolor=\"" + BorderColor + "\">" + Spacer1w2h + "</td>";
  562.   FormattedText += " </tr>";
  563.  
  564.   FormattedText += " <tr>";
  565.   FormattedText += "  <td height=7 bgcolor=\"" + BorderColor + "\">" + Spacer2w1h + "</td>";
  566.   FormattedText += "  <td height=7 colspan=3>" + Spacer1w7h + "</td>";
  567.   FormattedText += "  <td height=7 bgcolor=\"" + BorderColor + "\">" + Spacer2w1h + "</td>";
  568.   FormattedText += " </tr>";
  569.  
  570.   FormattedText += " <tr>";
  571.   FormattedText += "  <td bgcolor=\"" + BorderColor + "\">" + ReqSpacer2w1h + "</td>";
  572.   FormattedText += "  <td>" + ReqSpacer5w1h + "</td>";
  573.   FormattedText += "  <td width=\"100%\" id=\"" + ParamTextID + "\" style=\"color: " + ForegroundColor + " ; " + WWHFrame.WWHJavaScript.mSettings.mHoverText.mFontStyle + "\">" + ParamText + "</td>";
  574.   FormattedText += "  <td>" + ReqSpacer5w1h + "</td>";
  575.   FormattedText += "  <td bgcolor=\"" + BorderColor + "\">" + ReqSpacer2w1h + "</td>";
  576.   FormattedText += " </tr>";
  577.  
  578.   FormattedText += " <tr>";
  579.   FormattedText += "  <td height=7 bgcolor=\"" + BorderColor + "\">" + Spacer2w1h + "</td>";
  580.   FormattedText += "  <td height=7 colspan=3>" + Spacer1w7h + "</td>";
  581.   FormattedText += "  <td height=7 bgcolor=\"" + BorderColor + "\">" + Spacer2w1h + "</td>";
  582.   FormattedText += " </tr>";
  583.  
  584.   FormattedText += " <tr>";
  585.   FormattedText += "  <td height=2 colspan=5 bgcolor=\"" + BorderColor + "\">" + Spacer1w2h + "</td>";
  586.   FormattedText += " </tr>";
  587.   FormattedText += "</table>";
  588.  
  589.   return FormattedText;
  590. }
  591.  
  592. function  WWHIndex_GetPopupAction(ParamEntryInfo)
  593. {
  594.   var  PopupAction = "";
  595.  
  596.  
  597.   if (WWHFrame.WWHJavaScript.mSettings.mHoverText.mbEnabled)
  598.   {
  599.     PopupAction += " onMouseOver=\"fS('" + ParamEntryInfo + "', " + this.mEventString + ");\"";
  600.     PopupAction += " onMouseOut=\"fH();\"";
  601.   }
  602.  
  603.   return PopupAction;
  604. }
  605.  
  606. function  WWHIndex_ThresholdExceeded()
  607. {
  608.   var  bThresholdExceeded;
  609.  
  610.  
  611.   if ((this.mOptions.mThreshold > 0) &&
  612.       (this.mEntryCount > this.mOptions.mThreshold))
  613.   {
  614.     bThresholdExceeded = true;
  615.   }
  616.   else
  617.   {
  618.     bThresholdExceeded = false;
  619.   }
  620.  
  621.   return bThresholdExceeded;
  622. }
  623.  
  624. function  WWHIndex_GetSectionNavigation(ParamSection)
  625. {
  626.   var  SectionNavHTML = "";
  627.   var  SectionArray;
  628.   var  MaxIndex;
  629.   var  Index;
  630.  
  631.  
  632.   SectionNavHTML += "<p class=\"navigation\">";
  633.  
  634.   // Calculate section selection
  635.   //
  636.   SectionArray = this.mTopEntry.mChildrenSortArray;
  637.   for (MaxIndex = SectionArray.length, Index = 0 ; Index < MaxIndex ; Index++)
  638.   {
  639.     // Add spacers if necessary
  640.     //
  641.     if (Index > 0)
  642.     {
  643.       SectionNavHTML += this.mOptions.mSeperator;
  644.     }
  645.  
  646.     // Display section with or without link as necessary
  647.     //
  648.     if (Index == this.mSectionIndex)  // Currently being displayed
  649.     {
  650.       SectionNavHTML += SectionArray[Index].mText;
  651.     }
  652.     else if ((SectionArray[Index].mChildren == null) &&         // Always display group
  653.              (SectionArray[Index].mChildrenSortArray == null))  // SortArray null before sort, hash null after
  654.     {
  655.       SectionNavHTML += "<font color=\"" + WWHFrame.WWHJavaScript.mSettings.mIndex.mNavigationDisabledColor + "\">" + SectionArray[Index].mText + "</font>";
  656.     }
  657.     else
  658.     {
  659.       SectionNavHTML += "<a class=\"navigation\" href=\"javascript:fN(" + Index + ");\">" + SectionArray[Index].mText + "</a>";
  660.     }
  661.   }
  662.  
  663.   SectionNavHTML += "</p>";
  664.  
  665.   return SectionNavHTML;
  666. }
  667.  
  668. function  WWHIndex_ChangeSection(ParamSectionIndex)
  669. {
  670.   // Set section
  671.   //
  672.   this.mSectionIndex = ParamSectionIndex;
  673.  
  674.   // Reload panel
  675.   //
  676.   WWHFrame.WWHJavaScript.mPanels.fClearScrollPosition();
  677.   WWHFrame.WWHJavaScript.mPanels.fDisplayPanel();
  678. }
  679.  
  680. function  WWHIndex_SelectionListHeadHTML()
  681. {
  682.   var  HTML = new WWHStringBuffer_Object();
  683.   var  Level;
  684.  
  685.  
  686.   HTML.fAppend("<style type=\"text/css\">\n");
  687.   HTML.fAppend(" <!--\n");
  688.   HTML.fAppend("  a { text-decoration: none ;\n");
  689.   HTML.fAppend("      color: " + WWHFrame.WWHJavaScript.mSettings.mIndex.mEnabledColor + " }\n");
  690.   HTML.fAppend("  p { margin-top: 1pt ;\n");
  691.   HTML.fAppend("      margin-bottom: 1pt ;\n");
  692.   HTML.fAppend("      color: " + WWHFrame.WWHJavaScript.mSettings.mIndex.mDisabledColor + " ;\n");
  693.   HTML.fAppend("      " + WWHFrame.WWHJavaScript.mSettings.mIndex.mFontStyle + " }\n");
  694.   for (Level = 1 ; Level < 3 ; Level++)
  695.   {
  696.     HTML.fAppend("  p.l" + Level + " { margin-left: " + (WWHFrame.WWHJavaScript.mSettings.mIndex.mIndent * Level) + "pt }\n");
  697.   }
  698.   HTML.fAppend("  h2 { " + WWHFrame.WWHJavaScript.mSettings.mIndex.mFontStyle + " }\n");
  699.   HTML.fAppend(" -->\n");
  700.   HTML.fAppend("</style>\n");
  701.  
  702.   return HTML.fGetBuffer();
  703. }
  704.  
  705. function  WWHIndex_SelectionListBodyHTML()
  706. {
  707.   var  HTML = new WWHStringBuffer_Object();
  708.   var  BookList = WWHFrame.WWHHelp.mBooks.mBookList;
  709.   var  MaxBookIndex;
  710.   var  BookIndex;
  711.   var  BookListEntry;
  712.   var  LinkArray;
  713.   var  MaxLinkIndex;
  714.   var  LinkIndex;
  715.   var  Parts;
  716.   var  PrevLinkFileIndex;
  717.   var  LinkFileIndex;
  718.   var  LinkAnchor;
  719.   var  DocumentURL;
  720.  
  721.  
  722.   // Display multiple entry message
  723.   //
  724.   HTML.fAppend("<h2>");
  725.   HTML.fAppend(WWHFrame.WWHJavaScript.mMessages.mIndexSelectMessage1 + " ");
  726.   HTML.fAppend(WWHFrame.WWHJavaScript.mMessages.mIndexSelectMessage2);
  727.   HTML.fAppend("</h2>\n");
  728.  
  729.   // Display text of entry clicked
  730.   //
  731.   HTML.fAppend("<p><b>" + this.mClickedEntry.mText + "</b></p>\n");
  732.  
  733.   // Display each book's link for this entry
  734.   //
  735.   for (MaxBookIndex = BookList.length, BookIndex = 0 ; BookIndex < MaxBookIndex ; BookIndex++)
  736.   {
  737.     if (typeof this.mClickedEntry.mBookLinks[BookIndex] != "undefined")
  738.     {
  739.       BookListEntry = BookList[BookIndex];
  740.  
  741.       // Write the book's title
  742.       //
  743.       HTML.fAppend("<p> </p>\n");
  744.       HTML.fAppend("<p class=l1><nobr><b>" + BookListEntry.mTitle + "</b>");
  745.  
  746.       // Sort link array to group files with anchors
  747.       //
  748.       // Use for loop to copy entries to workaround bug/problem in IE 5.0 on Windows
  749.       //
  750.       LinkArray = new Array();
  751.       for (MaxLinkIndex = this.mClickedEntry.mBookLinks[BookIndex].length, LinkIndex = 0 ; LinkIndex < MaxLinkIndex ; LinkIndex++)
  752.       {
  753.         LinkArray[LinkIndex] = this.mClickedEntry.mBookLinks[BookIndex][LinkIndex];
  754.       }
  755.       LinkArray = LinkArray.sort();
  756.  
  757.       // Now display file links
  758.       //
  759.       PrevLinkFileIndex = null;
  760.       for (MaxLinkIndex = LinkArray.length, LinkIndex = 0 ; LinkIndex < MaxLinkIndex ; LinkIndex++)
  761.       {
  762.         // Determine link file index and anchor
  763.         //
  764.         Parts = LinkArray[LinkIndex].split("#");
  765.         LinkFileIndex = parseInt(Parts[0]);
  766.         if (Parts.length > 1)
  767.         {
  768.           LinkAnchor = "#" + Parts[1];
  769.         }
  770.         else
  771.         {
  772.           LinkAnchor = "";
  773.         }
  774.  
  775.         // Determine if all links for a single document have been processed
  776.         //
  777.         if ((PrevLinkFileIndex == null) ||
  778.             (LinkFileIndex != PrevLinkFileIndex))
  779.         {
  780.           HTML.fAppend("</nobr></p>\n");
  781.  
  782.           // Build up absolute link URL
  783.           //
  784.           DocumentURL = WWHFrame.WWHHelp.mBaseURL + BookListEntry.mDirectory + BookListEntry.mFiles.fFileIndexToHREF(LinkFileIndex) + LinkAnchor;
  785.           DocumentURL = WWHStringUtilities_RestoreEscapedSpaces(DocumentURL);
  786.           DocumentURL = WWHStringUtilities_EscapeURLForJavaScriptAnchor(DocumentURL);
  787.  
  788.           HTML.fAppend("<p class=l2><nobr>");
  789.           HTML.fAppend("<a href=\"javascript:WWHFrame.WWHIndex.fDisplayLink('" + DocumentURL + "');\">");
  790.           HTML.fAppend(BookListEntry.mFiles.fFileIndexToTitle(LinkFileIndex) + "</a>");
  791.         }
  792.         else
  793.         {
  794.           // Build up absolute link URL
  795.           //
  796.           DocumentURL = WWHFrame.WWHHelp.mBaseURL + BookListEntry.mDirectory + BookListEntry.mFiles.fFileIndexToHREF(LinkFileIndex) + LinkAnchor;
  797.           DocumentURL = WWHStringUtilities_RestoreEscapedSpaces(DocumentURL);
  798.           DocumentURL = WWHStringUtilities_EscapeURLForJavaScriptAnchor(DocumentURL);
  799.  
  800.           HTML.fAppend(", ");
  801.           HTML.fAppend("<a href=\"javascript:WWHFrame.WWHIndex.fDisplayLink('" + DocumentURL + "');\">");
  802.           HTML.fAppend((LinkIndex + 1) + "</a>");
  803.         }
  804.  
  805.         PrevLinkFileIndex = LinkFileIndex;
  806.       }
  807.  
  808.       HTML.fAppend("</nobr></p>\n");
  809.     }
  810.   }
  811.  
  812.   return HTML.fGetBuffer();
  813. }
  814.  
  815. function  WWHIndex_DisplayLink(ParamURL)
  816. {
  817.   WWHFrame.WWHHelp.fSetDocumentHREF(ParamURL, false);
  818. }
  819.  
  820. function  WWHIndex_GetEntry(ParamEntryInfo)
  821. {
  822.   var  Entry = null;
  823.   var  EntryInfoParts;
  824.   var  MaxIndex;
  825.   var  Index;
  826.  
  827.  
  828.   // Locate specified entry
  829.   //
  830.   Entry = this.mTopEntry;
  831.   EntryInfoParts = ParamEntryInfo.split(":");
  832.   for (MaxIndex = EntryInfoParts.length, Index = 0 ; Index < MaxIndex ; Index++)
  833.   {
  834.     Entry = Entry.mChildrenSortArray[EntryInfoParts[Index]];
  835.   }
  836.  
  837.   return Entry;
  838. }
  839.  
  840. function  WWHIndex_ClickedEntry(ParamEntryInfo)
  841. {
  842.   var  Entry;
  843.   var  BookCount;
  844.   var  BookIndex;
  845.   var  BookListEntry;
  846.   var  Parts;
  847.   var  LinkFileIndex;
  848.   var  LinkAnchor;
  849.   var  DocumentURL;
  850.  
  851.  
  852.   // Locate specified entry
  853.   //
  854.   Entry = this.fGetEntry(ParamEntryInfo);
  855.  
  856.   // Display target document or selection list
  857.   //
  858.   BookCount = 0;
  859.   for (BookIndex in Entry.mBookLinks)
  860.   {
  861.     BookCount++;
  862.   }
  863.  
  864.   // See if this is a single entry
  865.   //
  866.   if ((BookCount == 1) &&
  867.       (Entry.mBookLinks[BookIndex].length == 1))
  868.   {
  869.     BookListEntry = WWHFrame.WWHHelp.mBooks.mBookList[BookIndex];
  870.  
  871.     // Determine link file index and anchor
  872.     //
  873.     Parts = Entry.mBookLinks[BookIndex][0].split("#");
  874.     LinkFileIndex = parseInt(Parts[0]);
  875.     if (Parts.length > 1)
  876.     {
  877.       LinkAnchor = "#" + Parts[1];
  878.     }
  879.     else
  880.     {
  881.       LinkAnchor = "";
  882.     }
  883.  
  884.     // Set Document
  885.     //
  886.     DocumentURL = WWHFrame.WWHHelp.mBaseURL + BookListEntry.mDirectory + BookListEntry.mFiles.fFileIndexToHREF(LinkFileIndex) + LinkAnchor;
  887.   }
  888.   else
  889.   {
  890.     // Display selection list
  891.     //
  892.     this.mClickedEntry = Entry;
  893.     DocumentURL = WWHFrame.WWHHelp.mBaseURL + "wwhelp/wwhimpl/js/html/indexsel.htm";
  894.   }
  895.  
  896.   this.fDisplayLink(DocumentURL);
  897. }
  898.  
  899. function  WWHIndex_ClickedSeeAlsoEntry(ParamEntryInfo)
  900. {
  901.   var  Entry;
  902.   var  TargetSectionIndex;
  903.   var  MaxIndex;
  904.   var  Index;
  905.  
  906.  
  907.   // Locate specified entry
  908.   //
  909.   Entry = this.fGetEntry(ParamEntryInfo);
  910.  
  911.   // Confirm entry has target information
  912.   //
  913.   if ((typeof Entry.mSeeAlsoTargetName == "string") &&
  914.       (typeof Entry.mSeeAlsoTargetEntryKey == "string"))
  915.   {
  916.     TargetSectionIndex = null;
  917.  
  918.     // Determine if we need to jump to another page
  919.     //
  920.     if (this.fThresholdExceeded())
  921.     {
  922.       MaxIndex = this.mTopEntry.mChildrenSortArray.length;
  923.       Index = 0;
  924.       while ((TargetSectionIndex == null) &&
  925.              (Index < MaxIndex))
  926.       {
  927.         if (this.mTopEntry.mChildrenSortArray[Index].mText == Entry.mSeeAlsoTargetEntryKey)
  928.         {
  929.           TargetSectionIndex = Index;
  930.         }
  931.  
  932.         Index++;
  933.       }
  934.     }
  935.  
  936.     // Set target entry
  937.     //
  938.     this.mPanelAnchor = Entry.mSeeAlsoTargetName;
  939.  
  940.     if (((TargetSectionIndex != null) &&
  941.          (this.mSectionIndex != null)) &&
  942.         (TargetSectionIndex != this.mSectionIndex))
  943.     {
  944.       // Need to switch to proper section
  945.       //
  946.       this.fChangeSection(TargetSectionIndex);
  947.     }
  948.     else
  949.     {
  950.       // We're on the right page, so just jump to the correct entry
  951.       //
  952.       WWHFrame.WWHJavaScript.mPanels.fJumpToAnchor();
  953.     }
  954.   }
  955. }
  956.  
  957. function  WWHIndexIterator_Object()
  958. {
  959.   this.mIteratorScope      = null;
  960.   this.mEntry              = null;
  961.   this.mParentStack        = new Array();
  962.   this.mPositionStack      = new Array();
  963.   this.mbThresholdExceeded = false;
  964.   this.mStackOffset        = 1;
  965.  
  966.   this.fReset   = WWHIndexIterator_Reset;
  967.   this.fAdvance = WWHIndexIterator_Advance;
  968. }
  969.  
  970. function  WWHIndexIterator_Reset(ParamIndex,
  971.                                  bParamThresholdExceeded)
  972. {
  973.   if (ParamIndex == null)  // Iterate buckets as well!
  974.   {
  975.     this.mIteratorScope = WWHFrame.WWHIndex.mTopEntry;
  976.   }
  977.   else
  978.   {
  979.     this.mIteratorScope = WWHFrame.WWHIndex.mTopEntry.mChildrenSortArray[ParamIndex];
  980.   }
  981.   this.mEntry                = this.mIteratorScope;
  982.   this.mParentStack.length   = 0;
  983.   this.mPositionStack.length = 0;
  984.   this.mbThresholdExceeded   = bParamThresholdExceeded;
  985.   this.mStackOffset          = 1;
  986. }
  987.  
  988. function  WWHIndexIterator_Advance()
  989. {
  990.   // Advance to the next visible entry
  991.   //
  992.   if (this.mEntry != null)
  993.   {
  994.     // Check for children
  995.     //
  996.     if (this.mEntry.mChildren != null)
  997.     {
  998.       // Determine sort order if necessary
  999.       //
  1000.       if (this.mEntry.mChildrenSortArray == null)
  1001.       {
  1002.         WWHIndexEntry_SortChildren(this.mEntry);
  1003.       }
  1004.     }
  1005.  
  1006.     // Process children
  1007.     //
  1008.     if (this.mEntry.mChildrenSortArray != null)
  1009.     {
  1010.       // Modify stack offset as needed
  1011.       //
  1012.       if (( ! this.mbThresholdExceeded) &&
  1013.           (this.mEntry.mbBucket) &&
  1014.           ( ! this.mEntry.mbShow))
  1015.       {
  1016.         this.mStackOffset += 1;
  1017.       }
  1018.  
  1019.       this.mParentStack[this.mParentStack.length] = this.mEntry;
  1020.       this.mPositionStack[this.mPositionStack.length] = 0;
  1021.       this.mEntry = this.mEntry.mChildrenSortArray[0];
  1022.     }
  1023.     // If we've reached the iterator scope, we're done
  1024.     //
  1025.     else if (this.mEntry == this.mIteratorScope)
  1026.     {
  1027.       this.mEntry = null;
  1028.     }
  1029.     else
  1030.     {
  1031.       var  ParentEntry;
  1032.       var  StackTop;
  1033.  
  1034.  
  1035.       ParentEntry = this.mParentStack[this.mParentStack.length - 1];
  1036.       this.mEntry = null;
  1037.  
  1038.       // Find next child of parent entry
  1039.       //
  1040.       while (ParentEntry != null)
  1041.       {
  1042.         // Increment position
  1043.         //
  1044.         StackTop = this.mPositionStack.length - 1;
  1045.         this.mPositionStack[StackTop]++;
  1046.  
  1047.         // Confirm this is a valid entry
  1048.         //
  1049.         if (this.mPositionStack[StackTop] < ParentEntry.mChildrenSortArray.length)
  1050.         {
  1051.           // Return the parent's next child
  1052.           //
  1053.           this.mEntry = ParentEntry.mChildrenSortArray[this.mPositionStack[StackTop]];
  1054.  
  1055.           // Signal break from loop
  1056.           //
  1057.           ParentEntry = null;
  1058.         }
  1059.         else
  1060.         {
  1061.           // Last child of parent, try up a level
  1062.           //
  1063.           if (ParentEntry == this.mIteratorScope)
  1064.           {
  1065.             ParentEntry = null;
  1066.           }
  1067.           else
  1068.           {
  1069.             // Restore stack offset as needed
  1070.             //
  1071.             if (( ! this.mbThresholdExceeded) &&
  1072.                 (ParentEntry.mbBucket) &&
  1073.                 ( ! ParentEntry.mbShow))
  1074.             {
  1075.               this.mStackOffset -= 1;
  1076.             }
  1077.  
  1078.             ParentEntry = ParentEntry.mParent;
  1079.             this.mParentStack.length--;
  1080.             this.mPositionStack.length--;
  1081.  
  1082.             ParentEntry = this.mParentStack[this.mParentStack.length - 1];
  1083.           }
  1084.         }
  1085.       }
  1086.     }
  1087.   }
  1088.  
  1089.   return (this.mEntry != null);
  1090. }
  1091.  
  1092. function  WWHIndexTopEntry_Object()
  1093. {
  1094.   this.mLevel             = -1;
  1095.   this.mChildren          = null;
  1096.   this.mChildrenSortArray = null;
  1097.  
  1098.   this.fGetGroup = WWHIndexTopEntry_GetGroup;
  1099.   this.fAddEntry = WWHIndexTopEntry_AddEntry;
  1100.   this.fA        = WWHIndexTopEntry_AddEntry;
  1101. }
  1102.  
  1103. function  WWHIndexTopEntry_GetGroup(ParamGroupTitle)
  1104. {
  1105.   var  GroupEntry;
  1106.  
  1107.  
  1108.   // See if this object has any children
  1109.   //
  1110.   if (this.mChildren == null)
  1111.   {
  1112.     this.mChildren = new WWHIndexEntryHash_Object();
  1113.   }
  1114.  
  1115.   // Access entry, creating it if it doesn't exist
  1116.   //
  1117.   GroupEntry = this.mChildren[ParamGroupTitle + "~"];
  1118.   if (typeof GroupEntry == "undefined")
  1119.   {
  1120.     GroupEntry = new WWHIndexEntry_Object(0, 0, WWHStringUtilities_EscapeHTML(ParamGroupTitle), null, null);
  1121.     GroupEntry.mbGroup = true;
  1122.     this.mChildren[ParamGroupTitle + "~"] = GroupEntry;
  1123.   }
  1124.  
  1125.   return GroupEntry;
  1126. }
  1127.  
  1128. function  WWHIndexTopEntry_AddEntry(ParamText,
  1129.                                     ParamLinks,
  1130.                                     ParamSortKey,
  1131.                                     ParamSeeAlso)
  1132. {
  1133.   var  FirstChar = "";
  1134.   var  GroupTitle;
  1135.   var  GroupEntry;
  1136.   var  BucketEntry;
  1137.   var  NewEntry;
  1138.  
  1139.  
  1140.   // Grab first character
  1141.   //
  1142.   if ((typeof ParamSortKey == "string") &&
  1143.       (ParamSortKey.length > 0))
  1144.   {
  1145.     FirstChar = ParamSortKey.substring(0, 1);
  1146.  
  1147.     // Check for encoded characters
  1148.     //
  1149.     if (FirstChar == "&")
  1150.     {
  1151.       FirstChar = WWHStringUtilities_UnescapeHTML(ParamSortKey);
  1152.  
  1153.       FirstChar = FirstChar.substring(0, 1);
  1154.     }
  1155.  
  1156.     // toUpperCase is conditional to handle numbers
  1157.     //
  1158.     FirstChar = (typeof FirstChar.toUpperCase == "function") ? FirstChar.toUpperCase() : FirstChar;
  1159.   }
  1160.   else if (ParamText.length > 0)
  1161.   {
  1162.     FirstChar = ParamText.substring(0, 1);
  1163.  
  1164.     // Check for encoded characters
  1165.     //
  1166.     if (FirstChar == "&")
  1167.     {
  1168.       FirstChar = WWHStringUtilities_UnescapeHTML(ParamText);
  1169.  
  1170.       FirstChar = FirstChar.substring(0, 1);
  1171.     }
  1172.  
  1173.     // toUpperCase is conditional to handle numbers
  1174.     //
  1175.     FirstChar = (typeof FirstChar.toUpperCase == "function") ? FirstChar.toUpperCase() : FirstChar;
  1176.   }
  1177.  
  1178.   // Check for a group
  1179.   //
  1180.   GroupTitle = WWHFrame.WWHIndex.mOptions.mGroupMapping[FirstChar + "~"];
  1181.   if (typeof GroupTitle == "undefined")
  1182.   {
  1183.     GroupTitle = "";  // Put in required grouping
  1184.   }
  1185.  
  1186.   // Access group
  1187.   //
  1188.   GroupEntry = this.fGetGroup(GroupTitle);
  1189.  
  1190.   // Access bucket
  1191.   //
  1192.   BucketEntry = GroupEntry.fGetBucket(FirstChar, WWHFrame.WWHIndex.mOptions.mGroupInfoHash[GroupTitle + "~"].mbShowBuckets);
  1193.  
  1194.   // Add entry
  1195.   //
  1196.   NewEntry = BucketEntry.fAddEntry(ParamText, ParamLinks, ParamSortKey, ParamSeeAlso);
  1197.  
  1198.   return NewEntry;
  1199. }
  1200.  
  1201. function  WWHIndexEntry_Object(ParamBookIndex,
  1202.                                ParamLevel,
  1203.                                ParamText,
  1204.                                ParamLinks,
  1205.                                ParamSeeAlso)
  1206. {
  1207.   this.mText              = ParamText;
  1208.   this.mBookLinks         = null;
  1209.   this.mLevel             = ParamLevel;
  1210.   this.mChildren          = null;
  1211.   this.mChildrenSortArray = null;
  1212.  
  1213.   if (typeof ParamSeeAlso == "string")
  1214.   {
  1215.     this.mSeeAlso = ParamSeeAlso;
  1216.   }
  1217.  
  1218.   this.fGetBucket = WWHIndexEntry_GetBucket;
  1219.   this.fAddEntry  = WWHIndexEntry_AddEntry;
  1220.   this.fA         = WWHIndexEntry_AddEntry;
  1221.  
  1222.   // Bump MaxLevel if exceeded
  1223.   //
  1224.   if (WWHFrame.WWHIndex.mMaxLevel < this.mLevel)
  1225.   {
  1226.     WWHFrame.WWHIndex.mMaxLevel = this.mLevel;
  1227.   }
  1228.  
  1229.   // Bump entry count
  1230.   //
  1231.   WWHFrame.WWHIndex.mEntryCount++;
  1232.  
  1233.   // Add links
  1234.   //
  1235.   if ((typeof ParamLinks != "undefined") &&
  1236.       (ParamLinks != null))
  1237.   {
  1238.     this.mBookLinks = new WWHIndexEntryBookHash_Object();
  1239.     this.mBookLinks[ParamBookIndex] = ParamLinks;
  1240.   }
  1241. }
  1242.  
  1243. function  WWHIndexEntry_GetBucket(ParamText,
  1244.                                   bParamShow)
  1245. {
  1246.   var  BucketEntry;
  1247.  
  1248.  
  1249.   // See if this object has any children
  1250.   //
  1251.   if (this.mChildren == null)
  1252.   {
  1253.     this.mChildren = new WWHIndexEntryHash_Object();
  1254.   }
  1255.  
  1256.   // Access entry, creating it if it doesn't exist
  1257.   //
  1258.   BucketEntry = this.mChildren[ParamText + "~"];
  1259.   if (typeof BucketEntry == "undefined")
  1260.   {
  1261.     var  Level;
  1262.  
  1263.  
  1264.     // Keep level the same if buckets not visible
  1265.     //
  1266.     if (bParamShow)
  1267.     {
  1268.       Level = this.mLevel + 1;
  1269.     }
  1270.     else
  1271.     {
  1272.       Level = this.mLevel;
  1273.     }
  1274.  
  1275.     BucketEntry = new WWHIndexEntry_Object(0, Level, WWHStringUtilities_EscapeHTML(ParamText), null, null);
  1276.     BucketEntry.mbBucket            = true;
  1277.     BucketEntry.mbShow              = bParamShow;
  1278.     this.mChildren[ParamText + "~"] = BucketEntry;
  1279.   }
  1280.  
  1281.   return BucketEntry;
  1282. }
  1283.  
  1284. function  WWHIndexEntry_AddEntry(ParamText,
  1285.                                  ParamLinks,
  1286.                                  ParamSortKey,
  1287.                                  ParamSeeAlso)
  1288. {
  1289.   var  HashKey;
  1290.   var  ChildEntry;
  1291.   var  BookIndex = WWHFrame.WWHIndex.mInitIndex;
  1292.   var  Links     = null;
  1293.  
  1294.  
  1295.   // Set links if entries exist
  1296.   //
  1297.   if ((typeof ParamLinks != "undefined") &&
  1298.       (ParamLinks != null) &&
  1299.       (ParamLinks.length > 0))
  1300.   {
  1301.     Links = ParamLinks;
  1302.   }
  1303.  
  1304.   // See if this object has any children
  1305.   //
  1306.   if (this.mChildren == null)
  1307.   {
  1308.     this.mChildren = new WWHIndexEntryHash_Object();
  1309.   }
  1310.  
  1311.   // Access entry, creating it if it doesn't exist
  1312.   //
  1313.   HashKey = ((typeof ParamSortKey == "string") ? ParamSortKey : "") + ParamText;
  1314.   ChildEntry = this.mChildren[HashKey + "~"];
  1315.   if (typeof ChildEntry == "undefined")
  1316.   {
  1317.     ChildEntry = new WWHIndexEntry_Object(BookIndex, this.mLevel + 1, ParamText, Links, ParamSeeAlso);
  1318.     this.mChildren[HashKey + "~"] = ChildEntry;
  1319.  
  1320.     // Add entry to see also collection if it is a see also entry
  1321.     //
  1322.     if (typeof ParamSeeAlso == "string")
  1323.     {
  1324.       WWHFrame.WWHIndex.fAddSeeAlsoEntry(ChildEntry);
  1325.     }
  1326.   }
  1327.   else  // Child entry exists, update with new information
  1328.   {
  1329.     // Add book links
  1330.     //
  1331.     if (Links != null)
  1332.     {
  1333.       if (ChildEntry.mBookLinks == null)
  1334.       {
  1335.         ChildEntry.mBookLinks = new WWHIndexEntryBookHash_Object();
  1336.       }
  1337.  
  1338.       if (typeof ChildEntry.mBookLinks[BookIndex] == "undefined")
  1339.       {
  1340.         ChildEntry.mBookLinks[BookIndex] = Links;
  1341.       }
  1342.       else  // Append new links
  1343.       {
  1344.         var  BookLinks = ChildEntry.mBookLinks[BookIndex];
  1345.         var  MaxIndex;
  1346.         var  Index;
  1347.  
  1348.  
  1349.         for (MaxIndex = Links.length, Index = 0 ; Index < MaxIndex ; Index++)
  1350.         {
  1351.           BookLinks[BookLinks.length] = Links[Index];
  1352.         }
  1353.       }
  1354.     }
  1355.   }
  1356.  
  1357.   return ChildEntry;
  1358. }
  1359.  
  1360. function  WWHIndexEntry_SortChildren(ParamEntry)
  1361. {
  1362.   var  SortedArray;
  1363.  
  1364.  
  1365.   // Sort top entry according to group order
  1366.   //
  1367.   if (ParamEntry == WWHFrame.WWHIndex.mTopEntry)
  1368.   {
  1369.     var  GroupList = WWHFrame.WWHIndex.mOptions.mGroupList;
  1370.     var  MaxGroupIndex;
  1371.     var  GroupIndex;
  1372.     var  GroupEntry;
  1373.  
  1374.  
  1375.     // Accumulate entries in sort order
  1376.     //
  1377.     SortedArray = new Array();
  1378.     for (MaxGroupIndex = GroupList.length, GroupIndex = 0 ; GroupIndex < MaxGroupIndex ; GroupIndex++)
  1379.     {
  1380.       GroupEntry = ParamEntry.mChildren[GroupList[GroupIndex] + "~"];
  1381.       if (typeof GroupEntry != "undefined")
  1382.       {
  1383.         if (GroupList[GroupIndex].length == 0)  // Required group list found
  1384.         {
  1385.           // Sort required group entries
  1386.           //
  1387.           WWHIndexEntry_SortChildren(GroupEntry);
  1388.  
  1389.           // Add children to sorted array
  1390.           //
  1391.           for (MaxIndex = GroupEntry.mChildrenSortArray.length, Index = 0 ; Index < MaxIndex ; Index++)
  1392.           {
  1393.             SortedArray[SortedArray.length] = GroupEntry.mChildrenSortArray[Index];
  1394.  
  1395.             // Mark first required group entry
  1396.             //
  1397.             if (Index == 0)
  1398.             {
  1399.               SortedArray[SortedArray.length - 1].mbFirstRequiredEntry = true;
  1400.             }
  1401.           }
  1402.         }
  1403.         else
  1404.         {
  1405.           SortedArray[SortedArray.length] = GroupEntry;
  1406.         }
  1407.       }
  1408.     }
  1409.   }
  1410.   else
  1411.   {
  1412.     var  UnsortedArray;
  1413.     var  HashKey;
  1414.     var  SortKey;
  1415.     var  MaxIndex;
  1416.     var  Index;
  1417.  
  1418.  
  1419.     // Accumulate hash keys
  1420.     //
  1421.     UnsortedArray = new Array();
  1422.     for (HashKey in ParamEntry.mChildren)
  1423.     {
  1424.       // toUpperCase is conditional to handle numbers
  1425.       //
  1426.       SortKey = ((typeof HashKey.toUpperCase == "function") ? HashKey.toUpperCase() : HashKey) + "\n" + HashKey;
  1427.       UnsortedArray[UnsortedArray.length] = SortKey;
  1428.     }
  1429.  
  1430.     // Sort array
  1431.     //
  1432.     SortedArray = UnsortedArray.sort();
  1433.  
  1434.     // Replace sort keys with entries
  1435.     //
  1436.     for (MaxIndex = SortedArray.length, Index = 0 ; Index < MaxIndex ; Index++)
  1437.     {
  1438.       SortKey = SortedArray[Index];
  1439.       HashKey = SortKey.substring(SortKey.indexOf("\n") + 1, SortKey.length)
  1440.  
  1441.       SortedArray[Index] = ParamEntry.mChildren[HashKey];
  1442.     }
  1443.   }
  1444.  
  1445.   // Set children sort array
  1446.   // Clear hash table as it is no longer needed
  1447.   //
  1448.   ParamEntry.mChildrenSortArray = SortedArray;
  1449.   ParamEntry.mChildren = null;
  1450. }
  1451.  
  1452. function  WWHIndexEntryHash_Object()
  1453. {
  1454. }
  1455.  
  1456. function  WWHIndexEntryBookHash_Object()
  1457. {
  1458. }
  1459.  
  1460. function  WWHSectionCache_Object()
  1461. {
  1462. }
  1463.  
  1464. function  WWHIndexOptions_Object()
  1465. {
  1466.   this.mThreshold     = 0;
  1467.   this.mGroupList     = new Array();
  1468.   this.mGroupInfoHash = new WWHIndexOptionsGroupInfoHash_Object();
  1469.   this.mGroupMapping  = new WWHIndexOptionsGroupMapping_Object();
  1470.  
  1471.   this.fSetThreshold = WWHIndexOptions_SetThreshold;
  1472.   this.fSetSeperator = WWHIndexOptions_SetSeperator;
  1473.   this.fGroup        = WWHIndexOptions_Group;
  1474. }
  1475.  
  1476. function  WWHIndexOptions_SetThreshold(ParamThreshold)
  1477. {
  1478.   this.mThreshold = ParamThreshold;
  1479. }
  1480.  
  1481. function  WWHIndexOptions_SetSeperator(ParamSeperator)
  1482. {
  1483.   this.mSeperator = ParamSeperator;
  1484. }
  1485.  
  1486. function  WWHIndexOptions_Group(ParamGroupTitle,
  1487.                                 bParamAlwaysDisplay,
  1488.                                 bParamShowBuckets,
  1489.                                 ParamGroupEntries)
  1490. {
  1491.   var  GroupEntries;
  1492.   var  MaxIndex;
  1493.   var  Index;
  1494.  
  1495.  
  1496.   // Record display order
  1497.   //
  1498.   this.mGroupList[this.mGroupList.length] = ParamGroupTitle;
  1499.  
  1500.   // Record group info
  1501.   //
  1502.   if (ParamGroupTitle != "")
  1503.   {
  1504.     this.mGroupInfoHash[ParamGroupTitle + "~"] = new WWHIndexOptionsGroupInfo_Object(bParamAlwaysDisplay, bParamShowBuckets);
  1505.   }
  1506.   else  // Handle required group
  1507.   {
  1508.     this.mGroupInfoHash[ParamGroupTitle + "~"] = new WWHIndexOptionsGroupInfo_Object(true, bParamShowBuckets);
  1509.   }
  1510.  
  1511.   // Record entries for each group
  1512.   //
  1513.   GroupEntries = ParamGroupEntries.split("");
  1514.   for (MaxIndex = GroupEntries.length, Index = 0 ; Index < MaxIndex ; Index++)
  1515.   {
  1516.     if ((ParamGroupTitle.length == 0) ||                                        // Required items always have precendence
  1517.         (typeof this.mGroupMapping[GroupEntries[Index] + "~"] == "undefined"))  // Otherwise, prevent reseting entries
  1518.     {
  1519.       this.mGroupMapping[GroupEntries[Index] + "~"] = ParamGroupTitle;
  1520.     }
  1521.   }
  1522. }
  1523.  
  1524. function  WWHIndexOptionsGroupInfoHash_Object()
  1525. {
  1526. }
  1527.  
  1528. function  WWHIndexOptionsGroupInfo_Object(bParamAlwaysDisplay,
  1529.                                           bParamShowBuckets)
  1530. {
  1531.   this.mbAlwaysDisplay = bParamAlwaysDisplay;
  1532.   this.mbShowBuckets   = bParamShowBuckets;
  1533. }
  1534.  
  1535. function  WWHIndexOptionsGroupMapping_Object()
  1536. {
  1537. }
  1538.